package com.ml.mall.service.coupon.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ml.mall.bean.base.ApiRestResult;
import com.ml.mall.bean.page.Page;
import com.ml.mall.bean.req.coupon.*;
import com.ml.mall.bean.res.coupon.*;
import com.ml.mall.bean.vo.coupon.CouponVo;
import com.ml.mall.bean.vo.coupon.UsableCouponVo;
import com.ml.mall.consts.CommonConsts;
import com.ml.mall.entity.coupon.SysCoupon;
import com.ml.mall.entity.coupon.SysCouponProductRelation;
import com.ml.mall.entity.coupon.SysCouponSupplierRelation;
import com.ml.mall.entity.coupon.SysCouponSupplierUnuseProduct;
import com.ml.mall.entity.sys.SysUser;
import com.ml.mall.enums.CommonEnum;
import com.ml.mall.enums.RedisCacheEnum;
import com.ml.mall.enums.SysSeqNameEnum;
import com.ml.mall.exception.BizException;
import com.ml.mall.mapper.coupon.SysCouponMapper;
import com.ml.mall.mapper.coupon.SysCouponProductRelationMapper;
import com.ml.mall.mapper.coupon.SysCouponSupplierRelationMapper;
import com.ml.mall.mapper.coupon.SysCouponSupplierUnuseProductMapper;
import com.ml.mall.service.common.CommonSeqService;
import com.ml.mall.service.coupon.SysCouponService;
import com.ml.mall.service.variant.SysProductVariantSalesService;
import com.ml.mall.service.variant.SysProductVariantService;
import com.ml.mall.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;

@Slf4j
@Service
public class SysCouponServiceImpl extends ServiceImpl<SysCouponMapper, SysCoupon> implements SysCouponService {
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private CommonSeqService commonSeqService;
    @Autowired
    private SysCouponMapper sysCouponMapper;
    @Autowired
    private SysCouponSupplierUnuseProductMapper sysCouponSupplierUnuseProductMapper;
    @Autowired
    private SysCouponSupplierRelationMapper sysCouponSupplierRelationMapper;
    @Autowired
    private SysCouponProductRelationMapper sysCouponProductRelationMapper;
    @Autowired
    private SysProductVariantSalesService sysProductVariantSalesService;
    @Autowired
    private SysProductVariantService sysProductVariantService;

    @Transactional
    @Override
    public ApiRestResult createCoupon(CouponNewDto dto, SysUser user) {
        SysCoupon sysCoupon = new SysCoupon();
        BeanUtils.copyProperties(dto, sysCoupon);
        sysCoupon.setUseAmount(0);
        Long couponId = commonSeqService.nextSysOrderSeq(SysSeqNameEnum.SEQ_COUPON_ID.getCode());
        sysCoupon.setCouponCode(couponId.toString());
        sysCoupon.setCreater(user.getAcc());
        sysCoupon.setState(0);
        int isAdd = sysCouponMapper.insert(sysCoupon);
        if (isAdd < 1) {
            return ApiRestResult.err(CommonEnum.INSERT_ERROR);
        }
        if(dto.getCouponRelationDto() == null){
            return ApiRestResult.err(CommonEnum.INSERT_ERROR);
        }
        //非全局类型的优惠券
        if(!dto.getCouponType().equals(CommonConsts.COUPPON_TYPE_SYSTERM)){
            handleCouponRelation(dto.getCouponRelationDto(), sysCoupon, 1);
        }
        return ApiRestResult.ok();
    }

    @Transactional
    @Override
    public ApiRestResult editCoupon(CouponEditDto dto) {
        SysCoupon dbSysCoupon = sysCouponMapper.selectById(dto.getId());
        BeanUtils.copyProperties(dto, dbSysCoupon);
        int isUpdate = sysCouponMapper.updateById(dbSysCoupon);
        if (isUpdate < 1) {
            return ApiRestResult.err(CommonEnum.UPDATE_ERROR);
        }
        handleCouponRelation(dto.getCouponRelationDto(), dbSysCoupon, 2);
        return ApiRestResult.ok();
    }

//    @Transactional
    @Override
    public ApiRestResult removeCoupon(List<Long> ids) {
        //清除三个关联变的数据
        List<SysCoupon> sysCoupons = sysCouponMapper.selectBatchIds(ids);
        for(SysCoupon sysCoupon : sysCoupons){
            sysCouponProductRelationMapper.deleteByCouponCode(sysCoupon.getCouponCode());
            sysCouponSupplierRelationMapper.deleteByCouponCode(sysCoupon.getCouponCode());
            sysCouponSupplierUnuseProductMapper.deleteByCouponCode(sysCoupon.getCouponCode());
        }
        int isDel = sysCouponMapper.deleteBatchIds(ids);
        if (isDel < 1) {
            return ApiRestResult.err(CommonEnum.DELETE_ERROR);
        }


        return ApiRestResult.ok();
    }

    @Override
    public Page<CouponQueryRes> queryPageCoupon(CouponQueryDto dto) {
        Page<CouponQueryRes> page = new Page<>(dto.getPageIndex(), dto.getPageNum());
        //连表查询；承担者
        List<CouponQueryRes> couponQueryRes = sysCouponMapper.selectPageRes(dto);
        //查询数量
        int count = sysCouponMapper.selectPageCountRes(dto);
        page.setRecords(couponQueryRes);
        page.setTotal(count);
        return page;
    }

    @Override
    public CouponQueryInfoRes queryOneCoupon(CouponQueryOneDto dto) {
        CouponQueryInfoRes couponQueryInfoRes = new CouponQueryInfoRes();
        CouponRelationRes couponRelationRes = new CouponRelationRes();
        SysCoupon sysCoupon = sysCouponMapper.selectById(dto.getId());
        if (sysCoupon == null) {
            return null;
        }
        BeanUtils.copyProperties(sysCoupon, couponQueryInfoRes);
        getCouponInfo(couponRelationRes, sysCoupon);
        couponQueryInfoRes.setCouponRelationRes(couponRelationRes);
        return couponQueryInfoRes;
    }

    @Override
    public int editCouponUseAmount(String couponCode) {
        int isUpdate = sysCouponMapper.updateCouponUseAmount(couponCode);
        if (isUpdate < 1) {
            throw new BizException(CommonEnum.UPDATE_ERROR);
        }
        return isUpdate;
    }

    @Override
    public List<UsableCouponVo> queryUsableCoupon(CouponVo vo) {
        List<UsableCouponVo> canUsableList =   sysCouponMapper.selectUsableCoupon(vo);
        return canUsableList;
    }
    @Override
    public Boolean checkMultiCoupon( List<SysCoupon> dbCouponList) {
        log.info("dbCouponList===={}",dbCouponList);
        if(dbCouponList.size() == 0){
            return false;
        }
        //检测多张优惠券是否可以一起使用；每一张置否正常；是否促销；是否满足限制额度 在购物车中是否满足限额度；
        int mutualSum = 0;
        for (SysCoupon sysCoupon : dbCouponList) {
            // 1、多张优惠券是否互斥
            mutualSum += sysCoupon.getMutualType();
            if(mutualSum > 0 && dbCouponList.size() > 1){
                return false;
            }
            // 2、多张优惠券是否满足使用时间
            Calendar calendar = Calendar.getInstance();
            if(!calendar.getTime().after(sysCoupon.getTimeBegin()) || !calendar.getTime().before(sysCoupon.getTimeEnd())){
                return false;
            }
            //优惠券是否删除
            if(sysCoupon.getIsDelete().equals(1)){
                return false;
            }
            //优惠券是否状态正常
            if(sysCoupon.getState().equals(1)){
                return false;
            }
            //优惠券是否使用超过数量
            if(sysCoupon.getUseAmount() >= sysCoupon.getAmount()){
                return false;
            }
        }
        return true;
    }

    @Override
    public Boolean checkHaveAdminCouppon() {
        if(sysCouponMapper.selectAdminCouppon() != null){
            return true;
        }
        return false;
    }
//    @Override
//    public Boolean checkMultiCoupon(List<String> couponCodeList) {
//        LambdaQueryWrapper<SysCoupon> wrapper = new LambdaQueryWrapper<>();
//        wrapper.in(SysCoupon::getCouponCode,couponCodeList);
//        List<SysCoupon> dbCouponList = sysCouponMapper.selectList(wrapper);
//        if(dbCouponList.size() == 1){
//            return true;
//        }
//        int couponValue = 0;
//        int mutualSum = 0;
//        for (SysCoupon sysCoupon : dbCouponList) {
//            // 1、多张优惠券是否互斥
//            mutualSum += sysCoupon.getMutualType();
//            if(mutualSum > 0){
//                return false;
//            }
//            // 2、多张优惠券是否满足使用时间
//            Calendar calendar = Calendar.getInstance();
//            if(!calendar.getTime().after(sysCoupon.getTimeBegin()) || !calendar.getTime().before(sysCoupon.getTimeEnd())){
//                return false;
//            }
////            改为传入
////            String cartKey = ShoppingCartUtils.getCurShoppingCartKey();
//            String mapstr = (String)  redisUtil.hget(RedisCacheEnum.REDIS_SHOPPING_CART_CACHE.getCode(), "");
//            Map<String,Integer> productMap = JSONObject.parseObject(mapstr, HashMap.class);;
//            BigDecimal totalPrice = BigDecimal.ZERO;
//            for (String variantId : productMap.keySet()) {
//                log.info("当前购物车中数据为{},当前变体id为{}",productMap.keySet(),variantId);
//                // 3、判断优惠券使用的范围
//                if(sysCoupon.getCouponType() == 2){
//                    Long count = sysCouponSupplierRelationMapper.countSupplierUnUsableCoupon(sysCoupon.getCouponCode(),Long.valueOf(variantId));
//                    if(count > 0){  // 当优惠券相关表中存在不能使用优惠券的商品，则false
//                        return false;
//                    }
//                }
//                if(sysCoupon.getCouponType() == 3){
//                    Long count = sysCouponProductRelationMapper.countProductUsableCoupon(sysCoupon.getCouponCode(),Long.valueOf(variantId));
//                    if(count < 1){ // 当优惠券产品相关表中不存在使用优惠券的商品，则false
//                        return false;
//                    }
//                }
//                // 判断商品是否处于促销
//                BigDecimal salesPrice = sysProductVariantSalesService.getCurPromoByVariantId(Long.valueOf(variantId));
//                if(salesPrice != null && sysCoupon.getWithSales() == 0){
//                    return false;
//                }
//                // 查询产品售价
//                BigDecimal cellPrice = sysProductVariantService.findSkuPriceByVariantId(Long.valueOf(variantId));
//                BigDecimal price = salesPrice == null ? cellPrice : salesPrice;
//                totalPrice = totalPrice.add(price.multiply(new BigDecimal(productMap.get(variantId))));
//            }
//            // 3、判断优惠券使用的金额限制
//            log.info("购物车中总金额为【{}】",totalPrice);
//            // -1,0,1分别表示小于，等于，大于
//            if(totalPrice.compareTo(sysCoupon.getLowLimitMoney()) < 0 || totalPrice.compareTo(sysCoupon.getTopLimitMoney()) > 0){
//                return false;
//            }
//
//            //优惠券是否删除
//            //优惠券是否状态正常
//            //优惠券是否使用超过数量
//        }
//        return true;
//    }

    private void getCouponInfo(CouponRelationRes couponRelationRes, SysCoupon sysCoupon) {
        switch (sysCoupon.getCouponType()) {
            case 1:
            case 2:
                List<CouponSupplierRes> supplierList = sysCouponSupplierRelationMapper.selectSupplierByCouponCode(sysCoupon.getCouponCode());
                couponRelationRes.setSupplierRelationArr(supplierList);
                break;
            case 3:
                List<CouponSupplierRes> couponSupplierList = sysCouponSupplierRelationMapper.selectSupplierByCouponCode(sysCoupon.getCouponCode());
//              List<CouponProductRes> couponUnuseProductList = sysCouponSupplierUnuseProductMapper.selectUnuseProductByCouponCode(sysCoupon.getCouponCode());
                couponRelationRes.setSupplierRelationArr(couponSupplierList);
//              couponRelationRes.setUnuseProductRelationArr(couponUnuseProductList);
                break;
            case 4:
                List<CouponProductRes> couponProductList = sysCouponProductRelationMapper.selectProductByCouponCode(sysCoupon.getCouponCode());
                couponRelationRes.setProductRelationArr(couponProductList);
                break;
            default:
                throw new BizException(CommonEnum.ILLEGAL_REQ_ERROR);
        }
    }

    /**
     * @description :handelType，为2时，先删除，后新增  为1时，执行新增方法
     * @author :zxm
     * @date :2021/5/21
     **/
    private void handleCouponRelation(CouponRelationDto dto, SysCoupon sysCoupon, int handleType) {
        //所有的编辑必须传入现有的数据
        switch (sysCoupon.getCouponType()) {
            case 1:
                break;
            case  2:  //2 3 都执行3 java case 满足进入 直到 break 跳出 2后没有break 会执行三
            case  3:
                if (handleType == 2) {
                    sysCouponSupplierRelationMapper.deleteByCouponCode(sysCoupon.getCouponCode());
                    sysCouponSupplierUnuseProductMapper.deleteByCouponCode(sysCoupon.getCouponCode());
                }
                List<String> supplierList = dto.getSupplierRelationArr();
                if( supplierList != null && supplierList.size() > 0){
                    for (String id : supplierList) {
                        SysCouponSupplierRelation sysCouponSupplierRelation = new SysCouponSupplierRelation();
                        sysCouponSupplierRelation.setSupplierId(Long.valueOf(id));
                        sysCouponSupplierRelation.setCouponCode(sysCoupon.getCouponCode());
                        sysCouponSupplierRelationMapper.insert(sysCouponSupplierRelation);
                    }
                }

                List<CouponUnuseVariantDto> unuseProductList = dto.getUnuseProductRelationArr();
                if( unuseProductList != null && unuseProductList.size() > 0){
                    for (CouponUnuseVariantDto couponUnuseVariantDto : unuseProductList) {
                        SysCouponSupplierUnuseProduct unuseProductRelation = new SysCouponSupplierUnuseProduct();
                        unuseProductRelation.setVariantId(couponUnuseVariantDto.getVariantId());
                        unuseProductRelation.setCouponCode(sysCoupon.getCouponCode());
                        unuseProductRelation.setSupplierId(couponUnuseVariantDto.getSupplierId());
                        sysCouponSupplierUnuseProductMapper.insert(unuseProductRelation);
                    }
                }
                break;
            case 4:
                if (handleType == 2) {
                    sysCouponProductRelationMapper.deleteByCouponCode(sysCoupon.getCouponCode());
                }
                List<String> productList = dto.getProductRelationArr();
                if( productList != null && productList.size() > 0){
                    for (String id : productList) {
                        SysCouponProductRelation sysCouponProductRelation = new SysCouponProductRelation();
                        sysCouponProductRelation.setVariantId(Long.valueOf(id));
                        sysCouponProductRelation.setCouponCode(sysCoupon.getCouponCode());
                        sysCouponProductRelationMapper.insert(sysCouponProductRelation);
                    }
                }
                break;
            default:
                throw new BizException(CommonEnum.ILLEGAL_REQ_ERROR);
        }
    }




}
